package cn.wsalix.shiro;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import cn.anlaser.admin.BaseUser;
import cn.anlaser.utils.BeanMapper;
import cn.wsalix.admin.entity.MenuPermit;
import cn.wsalix.admin.entity.RequiresPermit;
import cn.wsalix.admin.entity.RequiresRole;
import cn.wsalix.admin.entity.SysRole;
import cn.wsalix.admin.entity.SysUser;
import cn.wsalix.admin.service.RoleService;
import cn.wsalix.admin.service.UserService;
import cn.wsalix.observable.service.LoginService;
import cn.wsalix.shiro.token.CaptchaToken;
import cn.wsalix.shiro.token.ThirdToken;

public class AuthRealm extends AuthorizingRealm {
	//private String adminAccount;
	private UserService userService;
	private RoleService roleService;
	private LoginService loginService;

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(
			PrincipalCollection principalCollection) {
		BaseUser user = (BaseUser) principalCollection.fromRealm(getName())
				.iterator().next();

		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		if (user.getUsername().equals("admin")) {		
			for (RequiresRole role : roleService.findRequiresRoles()) {
				info.addRole(role.getCode());
			}
			for (RequiresPermit menuPermit : roleService.findRequiresPermits()) {
				info.addStringPermission(menuPermit.getCode());
			}
		}
		for (SysRole role : roleService.findRolesByUserId(user.getId())) {
			info.addRole(role.getCode());
		}
		for (MenuPermit menuPermit : roleService.findPermitsByUserId(user
				.getId())) {
			info.addStringPermission(menuPermit.getCode());
		}
		return info;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken authenticationToken)
			throws AuthenticationException {
		SysUser user = null;
		BaseUser baseUser=null ;
		if (authenticationToken instanceof CaptchaToken) {
			CaptchaToken upToken = (CaptchaToken) authenticationToken;
			user = userService.findByUsername(upToken.getUsername());
			if (user == null) {
				throw new UnknownAccountException("No account found for user ["
						+ upToken.getUsername() + "]");
			}
			baseUser = BeanMapper.map(user, BaseUser.class);
			baseUser.setShopId(upToken.getShopId());
		} else if (authenticationToken instanceof ThirdToken) {
			ThirdToken upToken = (ThirdToken) authenticationToken;
			user = upToken.getUser();
			baseUser = BeanMapper.map(user, BaseUser.class);
			baseUser.setShopId(upToken.getShopId());
		}
		
		return new SimpleAuthenticationInfo(baseUser, baseUser.getPassword(),
				ByteSource.Util.bytes(baseUser.getCredentialsSalt()), getName());
	}

	public UserService getUserService() {
		return userService;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	public RoleService getRoleService() {
		return roleService;
	}

	public void setRoleService(RoleService roleService) {
		this.roleService = roleService;
	}

	public LoginService getLoginService() {
		return loginService;
	}

	public void setLoginService(LoginService loginService) {
		this.loginService = loginService;
	}

	@Override
	public void onLogout(PrincipalCollection principals) {
		BaseUser user = (BaseUser) principals.fromRealm(getName()).iterator()
				.next();
		user.setOnlineFlag(false);
		userService.onLogout(user.getId());
		super.onLogout(principals);
	}

/*	public String getAdminAccount() {
		return adminAccount;
	}

	public void setAdminAccount(String adminAccount) {
		this.adminAccount = adminAccount;
	}
*/
}
